package com.hys.app.service.erp.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hys.app.framework.util.BeanUtil;
import com.hys.app.framework.util.DateUtil;
import com.hys.app.mapper.erp.ChangeFormProductMapper;
import com.hys.app.model.erp.dos.ChangeFormProduct;
import com.hys.app.model.erp.dos.WarehouseEntryBatchDO;
import com.hys.app.model.erp.dto.ChangeFormProductDTO;
import com.hys.app.model.erp.dto.StockUpdateDTO;
import com.hys.app.model.erp.enums.NoBusinessTypeEnum;
import com.hys.app.model.erp.enums.StockChangeSourceEnum;
import com.hys.app.model.erp.enums.StockOperateEnum;
import com.hys.app.model.erp.vo.ChangeFormVO;
import com.hys.app.service.erp.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 换货单产品业务接口实现
 * @author dmy
 * 2023-12-05
 */
@Service
public class ChangeFormProductManagerImpl extends ServiceImpl<ChangeFormProductMapper, ChangeFormProduct> implements ChangeFormProductManager {

    @Autowired
    private ChangeFormProductMapper changeFormProductMapper;

    @Autowired
    private ChangeFormManager changeFormManager;

    @Autowired
    private WarehouseEntryBatchManager warehouseEntryBatchManager;

    @Autowired
    private NoGenerateManager noGenerateManager;

    /**
     * 新增换货单产品信息
     *
     * @param changeId 换货单ID
     * @param productList 产品信息集合
     * @param type 产品类型 0：退货，1：换货
     */
    @Override
    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveProduct(Long changeId, List<ChangeFormProductDTO> productList, Integer type) {
        //先删除旧数据
        List<Long> changeIds = new ArrayList<>();
        changeIds.add(changeId);
        this.deleteProduct(changeIds, type);

        //再循环将商品信息入库
        for (ChangeFormProductDTO productDTO : productList) {
            ChangeFormProduct product = new ChangeFormProduct();
            BeanUtil.copyProperties(productDTO, product);
            //设置换货单ID
            product.setChangeId(changeId);
            //设置产品类型
            product.setType(type);
            this.save(product);
        }
    }

    /**
     * 删除换货单产品信息
     *
     * @param changeIds 换货单ID集合
     * @param type 产品类型 0：退货，1：换货
     */
    @Override
    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteProduct(List<Long> changeIds, Integer type) {
        LambdaQueryWrapper<ChangeFormProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ChangeFormProduct::getChangeId, changeIds);
        wrapper.eq(ChangeFormProduct::getType, type);
        this.changeFormProductMapper.delete(wrapper);
    }

    /**
     * 根据换货单ID获取换货单产品信息集合
     *
     * @param changeId 换货单ID
     * @param type 产品类型 0：退货，1：换货
     * @return
     */
    @Override
    public List<ChangeFormProduct> list(Long changeId, Integer type) {
        return this.lambdaQuery()
                .eq(ChangeFormProduct::getChangeId, changeId)
                .eq(type != null, ChangeFormProduct::getType, type)
                .list();
    }

    /**
     * 修改换货单中的商品库存
     *
     * @param changeId 换货单ID
     * @param warehouseId 仓库ID
     */
    @Override
    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateProductStock(Long changeId, Long warehouseId) {
        //获取换货单信息
        ChangeFormVO changeFormVO = this.changeFormManager.getDetail(changeId);

        //获取换货单中的退货商品信息集合
        List<ChangeFormProduct> returnProductList = changeFormVO.getReturnList();
        //获取换货单中的换货商品信息集合
        List<ChangeFormProduct> changeProductList = changeFormVO.getChangeList();

        if (returnProductList.size() > 0) {
            List<WarehouseEntryBatchDO> batchDOS = new ArrayList<>();
            for (ChangeFormProduct changeFormProduct : returnProductList) {
                WarehouseEntryBatchDO batchDO = new WarehouseEntryBatchDO();
                batchDO.setWarehouseEntryId(changeFormProduct.getStockId());
                batchDO.setWarehouseEntrySn(changeFormProduct.getStockSn());
                batchDO.setWarehouseEntryItemId(changeFormProduct.getStockItemId());
                batchDO.setSn(noGenerateManager.generate(NoBusinessTypeEnum.WarehouseEntryBatch, changeFormVO.getDeptId()));
                batchDO.setWarehouseId(changeFormVO.getWarehouseId());
                batchDO.setGoodsId(changeFormProduct.getGoodsId());
                batchDO.setProductId(changeFormProduct.getProductId());
                batchDO.setProductSn(changeFormProduct.getProductSn());
                batchDO.setProductName(changeFormProduct.getProductName());
                batchDO.setProductSpecification(changeFormProduct.getSpecification());
                batchDO.setProductUnit(changeFormProduct.getUnit());
                batchDO.setCategoryId(changeFormProduct.getCategoryId());
                batchDO.setCategoryName(changeFormProduct.getCategoryName());
                batchDO.setEntryNum(changeFormProduct.getNum());
                batchDO.setEntryPrice(changeFormProduct.getAmount());
                batchDO.setProductCostPrice(changeFormProduct.getCostPrice());
                batchDO.setRemainNum(changeFormProduct.getNum());
                batchDO.setEntryTime(DateUtil.getDateline());
                batchDO.setWarehouseEntrySn(changeFormProduct.getStockSn());
                batchDOS.add(batchDO);
            }
            this.warehouseEntryBatchManager.create(StockChangeSourceEnum.CHANGE_FORM, changeFormVO.getSn(), batchDOS);
        }

        if (changeProductList.size() > 0) {
            List<StockUpdateDTO> updateList = new ArrayList<>();
            for (ChangeFormProduct changeFormProduct : changeProductList) {
                StockUpdateDTO stockUpdateDTO = new StockUpdateDTO();
                stockUpdateDTO.setBatchId(changeFormProduct.getStockBatchId());
                stockUpdateDTO.setBatchSn(changeFormProduct.getStockBatchSn());
                stockUpdateDTO.setChangeNum(changeFormProduct.getNum());
                stockUpdateDTO.setOperate(StockOperateEnum.Reduce);
                updateList.add(stockUpdateDTO);
            }
            this.warehouseEntryBatchManager.updateStock(StockChangeSourceEnum.CHANGE_FORM, changeFormVO.getSn(), updateList);
        }
    }
}
